{--


Q-Bot 0.0.1 alpha

This module defines all representations 


--}
module Representation where 

import Data.Array.Repa

-- ############# Envirnonment Representation #############

--card representation by a new datastructure
data Card = I|Zero|Succ|Dbl|Get|Put|S|K|Inc
            |Dec|Attack|Help|Copy|Revive|Zombie
           
--Maps a card to a integer                
card2Int::Card->Int
card2Int card = case card of
                            I -> 1
                            Zero -> 2
                            Succ -> 3
                            Dbl -> 4
                            Get -> 5
                            Put -> 6
                            S -> 7
                            K -> 8
                            Inc -> 9
                            Dec -> 10
                            Attack -> 11
                            Help -> 12
                            Copy -> 13
                            Revive -> 14
                            Zombie -> 15
                        
--Maps a card to a string                
card2String::Card->String
card2String card = case card of
                            I -> "I"
                            Zero -> "zero"
                            Succ -> "succ"
                            Dbl -> "dbl"
                            Get -> "get"
                            Put -> "put"
                            S -> "S"
                            K -> "K"
                            Inc -> "inc"
                            Dec -> "dec"
                            Attack -> "attack"
                            Help -> "help"
                            Copy -> "copy"
                            Revive -> "revive"
                            Zombie -> "zombie"
  
--Maps a int to a card
int2Card::Int->Card
int2Card i = case i of
                       1 -> I
                       2 -> Zero
                       3 -> Succ
                       4 -> Dbl
                       5 -> Get
                       6 -> Put
                       7 -> S
                       8 -> K
                       9 -> Inc
                       10 -> Dec
                       11 -> Attack
                       12 -> Help
                       13 -> Copy
                       14 -> Revive
                       15 -> Zombie
                       
--Maps a int to a card
string2Card::String->Card
string2Card i = case i of
                       "I" -> I
                       "zero" -> Zero
                       "succ" -> Succ
                       "dbl" -> Dbl
                       "get" -> Get
                       "put" -> Put
                       "S" -> S
                       "K" -> K
                       "inc" -> Inc
                       "dec" -> Dec
                       "attack" -> Attack
                       "help" -> Help
                       "copy" -> Copy
                       "revive" -> Revive
                       "zombie" -> Zombie
                       
                       
                       
                       

{--the envirnoment is a list of slots. 
--A Slot is a tuple. The first entry is the field's live, 
--the second is eather a card or an Integer. (Mabey better moddeled with Monads)? 
--The life of a field is in the range of -1 to 65535 and the integer of a slot is in the range of 0 to 65535.
--}

newtype Life = Life { lifeVal :: Int }
  deriving (Eq, Ord, Show)

makeLife :: Int -> Maybe Life
makeLife n
  | n >= -1 && n <=  65535 = Just (Life n)
  | otherwise = Nothing


data Field = Int | Card
type Slot = (Life, Field) -- <---- causes an error dont know why
type Envirnoment = [Slot]

--initializes the Envirnonment
initEnv::Envirnoment
initEnv=[(Life 1000, I)| _<-[1..256]]


--update envirnonment
updateEnv:: Int->Slot->Env->Env
updateEnv _ _ [] = []
updateEnv i slot (x:xs) 
                        | i == 0 = slot:xs
                        | otherwise = x:updateEnv (i - 1) slot xs

{--
A Game consits of the opponent's,proponents envirnonment as well as total life  from each slot the lifespan 
and the number of turns
--}

data Game = {
             pro.env::Enviroment,
             op.env::Environment,
             pro.life::Int,
             op.life::Int,
             turns::Int                   
             }deriving(Show) 
             
--inits a Game
initGame::Game
initGame = Game {pro.env = initEnv,
                 op.env = initEnv,
                 prob.life = 16776960,
                 op.life = 16776960,
                 turns = 0}  


{--
An action is consits of a card a integer to which the card is 
applyed and an integer {1,2} indicationg the application type
of the card.
--}
data App = 1|2

data Action = {
                card::Card
                field::Int
                app::App 
               }                              

-- ############# Q Representation  ###########
-- the Q-Array is represented as Repa.Array being able to mutate a single entry
-- the Array does have the following dimensions: 100000 rounds, 15 cards, 2 ways of applying a card, 
type Q = Array DIM4 Float

--remember only performe unsafe indexing !
initQ::Q
initQ = Data.Array.Repa.fromList (Z :. (100000::Int ):. (15::Int) :. (256::Int) :. (2::Int)) [0.0|_<-[1..768000000]]


                                   
--Calculates for given State, Card, Field and Acction the corresponding Index-Shape         
getIndex state card field action = (Z:. state :. (card2Int card) :. field :. action)                                        





 